package com.lzxuni.modules.wechat.config.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.lzxuni.common.utils.FileUtil;
import com.lzxuni.common.utils.JavaImageIOCreator;
import com.lzxuni.common.utils.StringUtils;
import com.lzxuni.common.utils.UuidUtil;
import com.lzxuni.common.utils.web.OkHttpUtil;
import com.lzxuni.config.AttachmentConfig;
import com.lzxuni.modules.common.entity.FileEntity;
import com.lzxuni.modules.common.entity.PageData;
import com.lzxuni.modules.common.service.FileEntityService;
import com.lzxuni.modules.wechat.config.entity.WechatUserInfo;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 公共微信工具类
 * Created by 潘云明
 * 2019/7/26 14:26
 */
@Controller

public class WeChatController {

    @Value("${lzxuni.wechat.APPID}")
    public String APPID;

    @Value("${lzxuni.wechat.APPSECRET}")
    public String APPSECRET;

    @Value("${lzxuni.wechat.URL}")
    public String URL;

    @Value("${lzxuni.wechat.PortUrl}")
    public String PortUrl;
    @Autowired
    private AttachmentConfig attachmentConfig;

    @Autowired
    private FileEntityService fileEntityService;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
    }

    public PageData getPageData(PageInfo<?> pageInfo) {
        List<?> list = pageInfo.getList();
        PageData pageData = new PageData();
        pageData.setRows(list);
        pageData.setTotal(pageInfo.getPages());
        pageData.setPage(pageInfo.getPageNum());
        pageData.setRecords(pageInfo.getTotal());
        pageData.setCosttime(10);
        return pageData;
    }


    public String getOpenId(HttpServletRequest req) {
        HttpSession session = req.getSession();
        return (String) session.getAttribute("openid");

    }

    public String getNickName(HttpServletRequest req) {
        HttpSession session = req.getSession();
        return (String) session.getAttribute("nickname");

    }

    public WechatUserInfo getWechatUserInfo(HttpServletRequest req) {
        HttpSession session = req.getSession();
        return (WechatUserInfo) session.getAttribute("userInfo");

    }

    public String getAddress(HttpServletRequest req) {
        String url = PortUrl + req.getRequestURI();
        if (StringUtil.isNotEmpty(req.getQueryString())) {
            url += "?" + req.getQueryString();
        }
        return url;
    }
    public String delHTMLTag(String htmlStr){
        String regEx_style="<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
        String regEx_html="<[^>]+>"; //定义HTML标签的正则表达式

        Pattern p_style= Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE);
        Matcher m_style=p_style.matcher(htmlStr);
        htmlStr=m_style.replaceAll(""); //过滤style标签

        Pattern p_html=Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);
        Matcher m_html=p_html.matcher(htmlStr);
        htmlStr=m_html.replaceAll(""); //过滤html标签

        htmlStr=htmlStr.replace(" ","");
        htmlStr=htmlStr.replaceAll("\\s*|\t|\r|\n","");
        htmlStr=htmlStr.replace("“","");
        htmlStr=htmlStr.replace("”","");
        htmlStr=htmlStr.replaceAll("　","");
        htmlStr=htmlStr.replaceAll("&nbsp;","");

        return htmlStr.trim(); //返回文本字符串
    }

    /**
     * 微信用
     */
    //access_token的失效时间
    private static long accessTokenExpiresTime;
    //sapiTicket的失效时间
    private static long jsapiTicketExpiresTime;
    //获取access_token的接口地址
    public static final String GET_ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    //获取jsapiTicket的接口地址
    public static final String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
    //获取临时文件URL
    public static final String Get_TEMP_FILE_URL = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
    //缓存的access_token
    private static String accessToken;
    //缓存的jsapiTicket
    private static String jsapiTicket;

    /**
     * 获取微信 AccessToken
     *
     * @return AccessToken
     */
    public String getAccessToken() {
        String s = "";
        try {


            if (accessToken == null || accessTokenExpiresTime < new Date().getTime()) {
                //发起请求获取accessToken
                s = OkHttpUtil.httpPost(GET_ACCESSTOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET));
                JSONObject jsonObject = (JSONObject) JSONObject.parse(s);
                accessToken = jsonObject.get("access_token").toString();
                //设置accessToken的失效时间
                long expires_in = jsonObject.getLong("expires_in");
                //失效时间 = 当前时间 + 有效期(提前一分钟)
                accessTokenExpiresTime = new Date().getTime() + (expires_in - 60) * 1000;
                System.out.println("new accessToken:" + s);
            }
        } catch (Exception e) {
            System.out.println("get accessToken error" + s);
        }

        return accessToken;
    }


    /**
     * 获取微信JsapiTicket
     *
     * @return JsapiTicket
     */
    public String getJsapiTicket() {
        if (jsapiTicket == null || jsapiTicketExpiresTime < new Date().getTime()) {
            //发起请求获取jsapiTicket
            String s = OkHttpUtil.httpPost(GET_JSAPI_TICKET_URL.replace("ACCESS_TOKEN", getAccessToken()));
            JSONObject jsonObject = (JSONObject) JSONObject.parse(s);
            jsapiTicket = jsonObject.get("ticket").toString();
            //设置jsapiTicket的失效时间
            long expires_in = jsonObject.getLong("expires_in");
            //失效时间 = 当前时间 + 有效期(提前一分钟)
            jsapiTicketExpiresTime = new Date().getTime() + (expires_in - 60) * 1000;
            System.out.println("new jsapiTicket:" + s);
        }
        return jsapiTicket;
    }


    /**
     * 获取微信js签名信息
     *
     * @param url
     * @return appId timestamp nonceStr signature
     */
    public Map<String, String> getJsAPiConfig(String url) {
        Map<String, String> map = new HashMap<>();
        String timestamp = new Date().getTime() / 1000 + "";
        String nonceStr = UUID.randomUUID().toString().replace("-", "");
        String jsapi_ticket = getJsapiTicket();
        String s = "jsapi_ticket=" + jsapi_ticket + "&" +
                "noncestr=" + nonceStr + "&" +
                "timestamp=" + timestamp + "&" +
                "url=" + url;
//        System.out.println("s:"+s);
        map.put("appId", APPID);
        map.put("timestamp", timestamp);
        map.put("nonceStr", nonceStr);
        map.put("signature", SHA1.encode(s));
        map.put("jsapi_ticket", jsapi_ticket);
        map.put("url", url);
        System.out.println("JsAPiConfig:" + map);
        return map;
    }

    /**
     * 下载微信图片
     *
     * @param media_id 微信serverID
     * @param typeName 业务名称
     * @param ywType   业务Type
     * @param ywid     住建ID
     * @param type     image
     */
    public void getTempFile(String media_id, String typeName, String ywType, String ywid, String type) {
        String date = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
        if (StringUtils.isEmpty(media_id)) {
            return;
        }
        String media_idList[] = media_id.split(",");
        for (int i = 0; i < media_idList.length; i++) {
            if (StringUtils.isEmpty(media_idList[i])) {
                continue;
            }
            try {
                java.net.URL u = new URL(Get_TEMP_FILE_URL.replace("ACCESS_TOKEN", getAccessToken()).replace("MEDIA_ID", media_idList[i]));
                HttpURLConnection conn = (HttpURLConnection) u.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(10000);
                conn.connect();
                BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
                String content_disposition = conn.getHeaderField("content-disposition");
                String content_length = conn.getHeaderField("content-length");
                String file_name = "";  //微信服务器生成的文件名称
                String fileNameB = "";//文件名后缀
                String[] content_arr = content_disposition.split(";");
                if (content_arr.length == 2) {
                    String tmp = content_arr[1];
                    int index = tmp.indexOf("\"");
                    file_name = tmp.substring(index + 1, tmp.length() - 1);
                }
                fileNameB = FileUtil.getFileExt(file_name);
                //生成不同文件名称
                String basePath = attachmentConfig.getPath();//D:/
                String realPath = "resource/" + date + "/";//D:/Resource/2018/06/29
                String fileName = UuidUtil.get32UUID() + "." + fileNameB;
                FileUtils.copyInputStreamToFile(bis, new File(basePath + realPath, fileName));
                if (type.equals("image")) {
                    // 获得图片宽高
                    BufferedImage srcImage = null;
                    srcImage = ImageIO.read(new File(basePath + realPath, fileName));
                    //Integer thumbHeight = srcImage.getHeight();
                    Integer thumbWidth = srcImage.getWidth();
                    JavaImageIOCreator creator = new JavaImageIOCreator(basePath + realPath + fileName, basePath + realPath + "s"
                            + fileName);
                    // 等比压缩
                    creator.resize(thumbWidth, 0.9);
                }
                FileEntity fileBean = new FileEntity();
                fileBean.setFileName(fileName);
                fileBean.setRealName(file_name);
                fileBean.setRealSize(Long.valueOf(content_length).longValue());
                fileBean.setRealPath(basePath + realPath + fileName);
                fileBean.setSfileName("s" + fileName);
                fileBean.setUrlPath("resource/" + date + "/" + fileName);
                fileBean.setUrlsPath("resource/" + date + "/" + "s" + fileName);
                fileEntityService.insert(JSON.toJSONString(fileBean).replace("&quot;", "\""), ywid, typeName, ywType, null);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }
}

class SHA1 {
    private static final char[] HEX = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }

    public static String encode(String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}